package window;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GraphicsConfiguration;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;

import org.eclipse.wb.swing.FocusTraversalOnArray;

import panels.ActorCollectionPanel;
import panels.ActorPanel;
import panels.CalculatorPanel;
import panels.DiceRoller;
import panels.LootPanel;
import panels.MapPanel;
import panels.PaintPanel;
import panels.UtilPanel;
import panels.util.HudDisplay;
import sprites.ActorSprite;
import sprites.Sprite;
import xml.Xml;

public class MainWindow implements WindowListener {

	private JFrame 					mainFrame;
	private JTextField 				messageWindow;
	private JPanel 					mainPanelEast;
	private	PaintPanel 				paintPanel;
	private ActorCollectionPanel	encounterPanel;
	private JFileChooser			fileChooser;
	private JTable xpTable;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {

					MainWindow		window = new MainWindow();
//					PlayerWindow	pWindow = new PlayerWindow();

					final GraphicsConfiguration config = window.mainFrame.getGraphicsConfiguration();


			        final int left = Toolkit.getDefaultToolkit().getScreenInsets(config).left;
			        final int right = Toolkit.getDefaultToolkit().getScreenInsets(config).right;
			        final int top = Toolkit.getDefaultToolkit().getScreenInsets(config).top;
			        final int bottom = Toolkit.getDefaultToolkit().getScreenInsets(config).bottom;

			        final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
			        final int width = screenSize.width - left - right;
			        final int height = screenSize.height - top - bottom;

			        window.mainFrame.setResizable(true);
			        window.mainFrame.setSize(width,height);
			        window.mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			        window.mainFrame.setVisible(true);

			        //
			        // Set the player window
			        //
//			        pWindow.setDM(window);
//			        pWindow.getFrame().setVisible(true);

			    } catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public MainWindow() {
		initialize();
	}

	/**
	 * Dispose of information on close
	 */

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {

		fileChooser = new JFileChooser();

		mainFrame = new JFrame();
		mainFrame.setTitle("RPG Utilities");
		mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		mainFrame.getContentPane().setLayout(new BorderLayout(0, 0));
		mainFrame.setBounds(0, 0, 1383, 792);

		HudDisplay hudDisplay = new HudDisplay();
		mainFrame.getContentPane().add(hudDisplay, BorderLayout.CENTER);
		hudDisplay.getLeftPanel().setLayout(new BorderLayout(0, 0));

		encounterPanel = new ActorCollectionPanel();
		hudDisplay.getLeftPanel().add(encounterPanel, BorderLayout.CENTER);
		hudDisplay.getCenterPanel().setLayout(new BorderLayout(0, 0));

		JPanel mainPanelCenter = new JPanel();
		hudDisplay.getCenterPanel().add(mainPanelCenter, BorderLayout.CENTER);
		mainPanelCenter.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Map", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		mainPanelCenter.setLayout(new BorderLayout(0, 0));

		JPanel mainPanelSouth = new JPanel();
		mainPanelCenter.add(mainPanelSouth, BorderLayout.SOUTH);
		mainPanelSouth.setBorder(new TitledBorder(null, "Chat", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		mainPanelSouth.setLayout(new BorderLayout(0, 0));

		JPanel recievePanelCenter = new JPanel();
		recievePanelCenter.setBorder(new TitledBorder(null, "Recieve", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		mainPanelSouth.add(recievePanelCenter, BorderLayout.CENTER);
		recievePanelCenter.setLayout(new BorderLayout(0, 0));

		JTextArea chatWindow = new JTextArea();
		chatWindow.setTabSize(4);
		chatWindow.setRows(4);
		chatWindow.setWrapStyleWord(true);
		chatWindow.setEditable(false);
		recievePanelCenter.add(chatWindow);

		JPanel sendPanelSouth = new JPanel();
		sendPanelSouth.setBorder(new TitledBorder(null, "Send", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		mainPanelSouth.add(sendPanelSouth, BorderLayout.SOUTH);
		sendPanelSouth.setLayout(new BoxLayout(sendPanelSouth, BoxLayout.X_AXIS));

		messageWindow = new JTextField();
		sendPanelSouth.add(messageWindow);
		messageWindow.setColumns(10);

		JButton sendButton = new JButton("Send");
		sendPanelSouth.add(sendButton);

		paintPanel = new PaintPanel();
		paintPanel.addPropertyChangeListener(new PropertyChangeListener() {
			public void propertyChange(PropertyChangeEvent e) {
				if (e!= null && e.getPropertyName() != null) {
					if (e.getPropertyName().compareTo(PaintPanel.SELECTED_SPRITE_PROPERTY)==0) {
						Sprite S = getPaintPanel().getSelectedSprite();
						if (S != null && S.getClass().equals(ActorSprite.class)) {
							ActorSprite AS = (ActorSprite) S;
							ActorPanel	AP = AS.getPanel();
							int			idx = encounterPanel.getActorTabs().indexOfComponent(AP);

							// Change the selected index to be the sprite we just clicked.
							encounterPanel.getActorTabs().setSelectedIndex(idx);
						}
					} else if (e.getPropertyName().compareTo(MapPanel.SPRITE_REMOVED_PROPERTY)==0) {
//						Sprite obj = (Sprite) e.getOldValue();
//						if (obj.getClass().equals(ActorSprite.class)) {
//							ActorSprite A = (ActorSprite) obj;
//							if (A.getPanel()!=null) {
//								encounterPanel.getActorTabs().remove(A.getPanel());
//							}
//						}
					}
				}
			}
		});
		mainPanelCenter.add(paintPanel, BorderLayout.CENTER);
		hudDisplay.getRightPanel().setLayout(new BorderLayout(0, 0));

		mainPanelEast = new JPanel();
		hudDisplay.getRightPanel().add(mainPanelEast, BorderLayout.CENTER);
		mainPanelEast.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Util", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		mainPanelEast.setLayout(new BorderLayout(0, 0));

		UtilPanel utilPanel = new UtilPanel();
		utilPanel.setBorder(new TitledBorder(null, "Util Panel", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		mainPanelEast.add(utilPanel, BorderLayout.CENTER);
		utilPanel.setLayout(new BorderLayout(0, 0));

		JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
		utilPanel.add(tabbedPane, BorderLayout.CENTER);

		LootPanel lootPanel = new LootPanel();
		tabbedPane.addTab("Loot", null, lootPanel, null);

		JPanel xpPanel = new JPanel();
		xpPanel.setBorder(new TitledBorder(null, "Xp Table", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		tabbedPane.addTab("Xp", null, xpPanel, null);
		xpPanel.setLayout(new BorderLayout(0, 0));

		JScrollPane scrollPane = new JScrollPane();
		xpPanel.add(scrollPane);

		xpTable = new JTable();
		xpTable.setModel(new DefaultTableModel(
			new Object[][] {
				{"1", "10", "20", "40"},
				{"2", "20", "40", "70"},
				{"3", "40", "60", "120"},
				{"4", "80", "130", "250"},
				{"5", "150", "250", "500"},
				{"6", "200", "300", "600"},
				{"7", "250", "350", "700"},
				{"8", "350", "550", "1050"},
				{"9", "400", "700", "1300"},
				{"10", "600", "900", "1700"},
				{"11", "900", "1300", "2600"},
				{"12", "1400", "2100", "4100"},
				{"13", "1700", "2600", "5100"},
				{"14", "2000", "3000", "5500"},
				{"15", "2500", "5500", "7000"},
				{"16", "3500", "6000", "10500"},
				{"17", "4000", "7000", "12000"},
				{"18", "4500", "7500", "14000"},
				{"19", "5000", "7500", "15000"},
				{"20", "6000", "9000", "17500"},
			},
			new String[] {
				"Level", "Easy", "Average", "Tough"
			}
		) {
			/**
			 *
			 */
			private static final long serialVersionUID = 1L;
			boolean[] columnEditables = new boolean[] {
				true, true, true, false
			};
			public boolean isCellEditable(int row, int column) {
				return columnEditables[column];
			}
		});
		xpTable.setEnabled(false);
		scrollPane.setViewportView(xpTable);

		CalculatorPanel calculatorPanel = new CalculatorPanel();
		tabbedPane.addTab("Calculator", null, calculatorPanel, null);

		DiceRoller diceRoller = new DiceRoller();

		mainPanelEast.add(diceRoller, BorderLayout.NORTH);

		JMenuBar menuBar = new JMenuBar();
		mainFrame.setJMenuBar(menuBar);

		JMenu mnFile = new JMenu("File");
		menuBar.add(mnFile);

		JMenu mnLoad = new JMenu("Load");
		mnFile.add(mnLoad);

		JMenuItem mntmLoadActor = new JMenuItem("Actor");
		mnLoad.add(mntmLoadActor);

		JMenuItem mntmLoadEncounter = new JMenuItem("Encounter");
		mnLoad.add(mntmLoadEncounter);

		JMenuItem mntmLoadMap = new JMenuItem("Map");
		mnLoad.add(mntmLoadMap);

		JMenuItem mntmLoadEverything = new JMenuItem("Everything");
		mntmLoadEverything.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				chooseLoadEverything();
			}
		});
		mnLoad.add(mntmLoadEverything);

		JMenu mnSave = new JMenu("Save");
		mnFile.add(mnSave);

		JMenuItem mntmSaveActor = new JMenuItem("Actor");
		mnSave.add(mntmSaveActor);

		JMenuItem mntmSaveEncounter = new JMenuItem("Encounter");
		mnSave.add(mntmSaveEncounter);

		JMenuItem mntmSaveMap = new JMenuItem("Map");
		mnSave.add(mntmSaveMap);

		JMenuItem mntmSaveEverything = new JMenuItem("Everything");
		mntmSaveEverything.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				chooseSaveEverything();
			}
		});
		mnSave.add(mntmSaveEverything);
		mainFrame.setFocusTraversalPolicy(new FocusTraversalOnArray(new Component[]{paintPanel}));
	}

	public String toXml() {
		String	paintPanelXml		= getPaintPanel().toXml();
		String	encounterPanelXml	= getEncounterPanel().toXml();

		return Xml.write("RpgUtil", paintPanelXml + encounterPanelXml);
	}

	public void fromXml(String xml) {
		String	rpgUtilXml			= Xml.getTag(xml, "RpgUtil");

		getPaintPanel().fromXml(rpgUtilXml);
		getEncounterPanel().fromXml(rpgUtilXml);
	}
	public PaintPanel getPaintPanel() {
		return paintPanel;
	}
	public ActorCollectionPanel getEncounterPanel() {
		return encounterPanel;
	}

	public void chooseSaveEverything() {
		fileChooser.showSaveDialog(fileChooser);
		File	F = fileChooser.getSelectedFile();
		if (F!=null) {
			saveEverything(F.getAbsolutePath());
		}
	}

	public void chooseLoadEverything() {
		fileChooser.showOpenDialog(fileChooser);
		File	F = fileChooser.getSelectedFile();
		if (F!=null) {
			loadEverything(F.getAbsolutePath());
		}
	}

	public void saveEverything(String filename) {
		if (filename!=null) {
			PrintWriter writer = null;
			try {
				writer = new PrintWriter(filename, "UTF-8");
				writer.println(toXml());
				writer.close();
			} catch (IOException ex) {
				System.err.println("Could not write everything to " + filename);
			} finally {
			   try { writer.close(); } catch (Exception ex) {}
			}
		}
	}

	public void loadEverything(String filename) {
		   String content = null;
		   File file = new File(filename); //for ex foo.txt
		   try {
		       FileReader reader = new FileReader(file);
		       char[] chars = new char[(int) file.length()];
		       reader.read(chars);
		       content = new String(chars);
		       fromXml(content);
		       reader.close();
		   } catch (IOException e) {
		       e.printStackTrace();
		   }
	}

	@Override
	public void windowOpened(WindowEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void windowClosing(WindowEvent e) {
		//
		// By default we will save to the last thing we loaded from or saved to.
		//
		File	F = fileChooser.getSelectedFile();
		if (F!=null) {
			saveEverything(F.getAbsolutePath());
		}
	}

	@Override
	public void windowClosed(WindowEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void windowIconified(WindowEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void windowDeiconified(WindowEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void windowActivated(WindowEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void windowDeactivated(WindowEvent e) {
		// TODO Auto-generated method stub

	}
	public JFrame getMainFrame() {
		return mainFrame;
	}
}
